import datetime
import time
import pdb

import MSLogger
import MSData

import pymssql


def now():
    return datetime.datetime.fromtimestamp(time.time())
def nowPastTenMinutes():
    return now() - datetime.timedelta(0, 60)

def getBeginEnd(LastEventRTime):
    begin = None
    if LastEventRTime != None:
        begin = LastEventRTime
    else:
        begin = nowPastTenMinutes()
    end = now()
    return (begin.strftime(MSData.TIME_FORMAT_MAGICDB), end.strftime(MSData.TIME_FORMAT_MAGICDB))

def parseEventLinePGSM(EventTuple):
    e = {}
    e["type"]     = EventTuple[2]
    e["datetime"] = EventTuple[1].strftime(MSData.TIME_FORMAT_MAGIC)
    return e

def parseEventLineContactId(EventTuple):
    e = {}
    cid = ''
    for i in EventTuple[2]:
        t = str(hex(ord(i)))
        if len(t) == 3:
            t = '0%s' % (t[2])
        else:
            t = '%s%s' % (t[2], t[3])
        cid += t
    #MSLogger.logDebug('Reader: raw(%s) cid(%s)' % (EventTuple[2], cid))
    e["value"] = cid
    e["date"] = EventTuple[1].strftime(MSData.TIME_FORMAT_MAGIC)
    return e




class Reader:
    def __init__(self, Host, Port, DatabaseName, User, Password):
        self.DBHost = Host
        self.DBPort = Port
        self.DBName = DatabaseName
        self.DBUser = User
        self.DBPass = Password
        self.connection = None

    def connect(self):
        attemptCount = 0
        self.connection = None
        while True:
            try:
                self.connection = pymssql.connect(host= self.DBHost + ':' + self.DBPort,
                                                  database=self.DBName,
                                                  user=self.DBUser, password=self.DBPass)
                break
            except:
                secs = 2
                attemptCount += 1
                if attemptCount > 3:
                    attemptCount = 0
                    secs *= 10
                MSLogger.logWarn('Connection failed to PCN FB(%s@%s). Sleep %d secs before new attempt' % (self.dbPath, self.dbUser, secs))
                sleep(secs)
                continue
        return True

    def forceConnection(self):
        #TBD check by getting cursor: except - reconn, not - ok
        if self.connection == None:
            self.connect()
            MSLogger.logDebug('Connected to MSSQL DB')
        return True

    def readEvents_PGSM(self, MSObjects):
        for obj in MSObjects:
            try:
                timeRange = getBeginEnd(obj.lastEvent_PGSM)
                cur = self.connection.cursor()
                query = "SELECT deviceId,eventTime,type FROM _event_data_internal WHERE eventTime>'%s' AND deviceId=%s" % (str(timeRange[0]), str(obj.objectMSId))
                cur.execute(query)
                events = cur.fetchall()
                for s in events:
                    try:
                        e = MSData.MSEvent()
                        e.fromPGSM(parseEventLinePGSM(s))
                        e.objectId = obj.objectPCNId
                        obj.eventsPGSM.append(e)
                        obj.lastEvent_PGSM = e.eventReceiveTime
                    except Exception, err:
                        MSLogger.logDebug('Reader: PGSM: event(%s) error(%s)' % (str(s), str(err)))
                        continue
                MSLogger.logInfo('Reader: PGSM: object(%s/%s) processed (%d/%d) events of (%s,%s)' % (str(obj.objectMSId), str(obj.objectPCNId), len(obj.eventsContactId), len(events), str(timeRange[0]), str(timeRange[1])))
            except Exception, err:
                MSLogger.logError('Reader: PGSM: object processing failed: error(%s)' % (str(err)))
                continue

    def readEvents_ContactId(self, MSObjects):
        for obj in MSObjects:
            try:
                timeRange = getBeginEnd(obj.lastEvent_ContactId)
                cur = self.connection.cursor()
                query = "SELECT deviceId,eventTime,contactData FROM _contactId_data_internal WHERE eventTime>'%s' AND deviceId=%s" % (str(timeRange[0]), str(obj.objectMSId))
                cur.execute(query)
                events = cur.fetchall()		
                for s in events:
                    try:
                        e = MSData.MSEvent()
                        e.fromContactId(parseEventLineContactId(s))
                        e.objectId = obj.objectPCNId
                        obj.eventsContactId.append(e)
                        obj.lastEvent_ContactId = e.eventReceiveTime
                    except Exception, err:
                        MSLogger.logWarn('Reader: ContactId: event(%s) error(%s)' % (str(s), str(err)))
                        continue
                MSLogger.logInfo('Reader: ContactId: object(%s/%s) processed (%d/%d) events of (%s,%s)' % (str(obj.objectMSId), str(obj.objectPCNId), len(obj.eventsContactId), len(events), str(timeRange[0]), str(timeRange[1])))
            except Exception, err:
                MSLogger.logError('Reader: ContactId: object processing failed: error(%s)' % (str(err)))
                continue

